/**
********************************************************************************
* @file     lv_port_indev_keyboard.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2024-07-11 23:22:28
* @copyright Copyright &copy; 2024 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
********************************************************************************
* @note
* None.
********************************************************************************
* @attention
* None.
********************************************************************************
@verbatim
@endverbatim
********************************************************************************
* @par 历史记录
* jcai, 2024-07-11 23:22:28
* - 首次编写
*
*<center>Copyright &copy; 2024 wy1107412334@163.com All rights reserved</center>
********************************************************************************
*/

/* 头文件导入区 ------------------------------------------------------------- */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "lv_port_indev_keyboard.h"
#include "sdl_render.h"


/** @defgroup LV_PORT_INDEV_KEYBOARD LV_PORT_INDEV_KEYBOARD
* @brief lv_port_indev_keyboard modules
* @{
*/



/* 私有宏定义区 ------------------------------------------------------------- */






/* 私有数据类型声明区 ------------------------------------------------------- */

typedef struct _keyboard_data
{
    sdl_event_handle_arr_t eventsInfo;
    SDL_KeyboardEvent keyboardData;
} keyboard_data;

static void keyboard_event(const SDL_Event *, void *, void *);






/* 私有变量定义区 ----------------------------------------------------------- */

static sdl_event_handle_t events[] = {
    { .type = SDL_KEYDOWN, .fn = keyboard_event, .arg = NULL },
    { .type = SDL_KEYUP, .fn = keyboard_event, .arg = NULL },
};




/** @defgroup LV_PORT_INDEV_KEYBOARD_Exported_Variables lv_port_indev_keyboard exported variables
* @brief 全局变量定义
* @{
*/



/** defgroup LV_PORT_INDEV_KEYBOARD_Exported_Variables
* @}
*/





/* 私有函数定义区 ----------------------------------------------------------- */

static void keyboard_event(const SDL_Event * e, void * lvglDrv, void * arg)
{
    (void) arg;

    keyboard_data * p = lv_indev_get_driver_data(lvglDrv);
    if (p == NULL)  return;

    if ((e->type == SDL_KEYDOWN) || (e->type == SDL_KEYUP))
    {
        p->keyboardData = e->key;
    }
}

static bool keyboard_is_pressed(keyboard_data * p)
{
    if (p->keyboardData.state == SDL_PRESSED)   return true;
    return false;
}

static void keyboard_read(lv_indev_t * indev, lv_indev_data_t * data)
{
    keyboard_data * p = lv_indev_get_driver_data(indev);

    static uint32_t last_key = 0;
    if (keyboard_is_pressed(p))
    {
        data->state = LV_INDEV_STATE_PRESSED;

        switch (p->keyboardData.keysym.sym)
        {
        case SDLK_PAGEUP:
            last_key = LV_KEY_PREV;
            break;
        case SDLK_PAGEDOWN:
            last_key = LV_KEY_NEXT;
            break;
        case 0x0d:  /* enter key */
            last_key = LV_KEY_ENTER;
            break;
        case SDLK_UP:
            last_key = LV_KEY_UP;
            break;
        case SDLK_DOWN:
            last_key = LV_KEY_DOWN;
            break;
        case SDLK_LEFT:
            last_key = LV_KEY_LEFT;
            break;
        case SDLK_RIGHT:
            last_key = LV_KEY_RIGHT;
            break;
        case SDLK_ESCAPE:
            last_key = LV_KEY_ESC;
            break;
        case SDLK_DELETE:
            last_key = LV_KEY_DEL;
            break;
        case SDLK_BACKSPACE:
            last_key = LV_KEY_BACKSPACE;
            break;
        case SDLK_HOME:
            last_key = LV_KEY_HOME;
            break;
        case SDLK_END:
            last_key = LV_KEY_END;
            break;
        default:
            data->state = LV_INDEV_STATE_RELEASED;
            break;
        }
    }
    else
    {
        data->state = LV_INDEV_STATE_RELEASED;
    }

    data->key = last_key;
}







/** @defgroup LV_PORT_INDEV_KEYBOARD_Exported_Functions lv_port_indev_keyboard exported functions
* @brief 全局函数定义
* @{
*/



/**
********************************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
void lv_port_indev_keyboard_init(void)
{
    keyboard_data * p = malloc(sizeof(*p));
    if (p == NULL)  return;
    bzero(p, sizeof(*p));

    lv_indev_t * indev_keyboard = lv_indev_create();
    lv_indev_set_type(indev_keyboard, LV_INDEV_TYPE_KEYPAD);
    lv_indev_set_read_cb(indev_keyboard, keyboard_read);
    lv_indev_set_driver_data(indev_keyboard, p);
    lv_indev_set_group(indev_keyboard, lv_group_get_default()); /* 关联默认组 */

    p->eventsInfo.lvglDrv = indev_keyboard;
    p->eventsInfo.arr = events;
    p->eventsInfo.arrlen = sizeof(events) / sizeof(events[0]);

    void * handle = lv_display_get_driver_data(lv_indev_get_display(indev_keyboard));
    sdl_event_listen(handle, &p->eventsInfo);
}


/** defgroup LV_PORT_INDEV_KEYBOARD_Exported_Functions
* @}
*/

/** defgroup LV_PORT_INDEV_KEYBOARD
* @}
*/


/*********************************** END OF FILE ******************************/
